package com.mtiiot.server.netty;



import com.mtiiot.server.BaseDataHandler;
import com.mtiiot.server.DataHandler;
import com.mtiiot.util.AddressUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import com.mtiiot.util.Constants;
import com.mtiiot.util.Utils;
import com.mtiiot.proto.Data.Group;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

import java.net.InetSocketAddress;

public class TimeServerHandler extends ChannelHandlerAdapter {
    private static Logger logger = LogManager.getLogger(TimeServerHandler.class);

    //	public static int connectCount =0;
//	public static int historymaxConnectCount =0;//历史最大连接数
    @Override
    public synchronized void channelActive(ChannelHandlerContext ctx) throws Exception {
//		connectCount++;
//		//logger.info("a new client connected with server!");
//		logger.info("new client in, current num:"+connectCount);
//		if(connectCount>historymaxConnectCount){
//			historymaxConnectCount=connectCount;
//		}
//		logger.info("history max connect num:"+historymaxConnectCount);
    }

    @Override
    public synchronized void channelInactive(ChannelHandlerContext ctx) throws Exception {
//		connectCount--;
//		logger.info("a client out, current num:"+connectCount);
//		logger.info("history max connect num:"+historymaxConnectCount);
    }

    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) {
        Group g = null;
        try {
            // 获取客户端的IP，host名字
            InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress();
            Constants.CLIENT_HOST_NAME = inSocket.getHostName();
            Constants.CLIENT_HOST_IP = inSocket.getAddress().getHostAddress();

            ByteBuf buf = (ByteBuf) msg;
            byte[] msgByte = new byte[buf.readableBytes()];
            buf.readBytes(msgByte);
            g = Group.parseFrom(msgByte);
            DataHandler dataHandle = BaseDataHandler.getDataHandlerByGroup(g);
            //1.写备份文件到本地
            dataHandle.writeStringToFile(g.getBody(), false);

            //记录info日志
            //Constants.getLogService().sendLog(SysName.SYSNAME_NETTY,LogLevel.IINFO,"收到文件信息","TimeServerHandler","channelRead",g.getCode()+"_"+g.getSeqNo(),"",Constants.config.getServerIp());
            // 2.验证数据
            boolean f = dataHandle.validateDynamicPwd();
            if (!f) {
                // 根据IP获取归属地信息
                String addressDetailed = AddressUtils.getAddressByIp(Constants.CLIENT_HOST_IP);
                // 将group信息转为string
                String gStr = Constants.groupToString(g);
                String errorMsg = "验证group信息异常," + Constants.EXCEPRION_TYPE_VALIDEFAILURE +
                        "\r\n,客户端名字:" + Constants.CLIENT_HOST_NAME +
                        "\r\n,客户端IP:" + Constants.CLIENT_HOST_IP +
                        "\r\n,客户端IP详细信息:" + addressDetailed +
                        "\r\n,group内容为:" + gStr;
                // 本地日志记录
                logger.error(errorMsg);
                // 将日志发往服务平台
                MetadataInfo logMetadataInfo = new MetadataInfo();
                logMetadataInfo.setSysId(Constants.config.getSysId());
                logMetadataInfo.setHost(Constants.config.getServerIp());
                Constants.getLogService().sendLog(logMetadataInfo, LogLevel.ERROR, "NETTY", errorMsg);
                // 回复客户端
                Group group = BaseDataHandler.handleFilure(Constants.EXCEPRION_TYPE_VALIDEFAILURE);
                byte[] respUtf8 = group.toByteArray();
                respUtf8 = Utils.byteMerger(respUtf8, Constants.config.getSeparator().getBytes());
                ByteBuf resp = PooledByteBufAllocator.DEFAULT
                        .buffer(respUtf8.length);
                resp.writeBytes(respUtf8);
                ctx.writeAndFlush(resp);
                ctx.disconnect();
            } else {
                // 3：正确接收,开始处理数据
                Group group = dataHandle.dataProcessCenter();
//				long end = System.currentTimeMillis();
//				long exeTime=end-start;
//				long byteArrlen=msgByte.length;
                //float dataSize=Utils.bytes2kb(byteArrlen);
//				InetSocketAddress remoteAdd=(InetSocketAddress) ctx.channel().remoteAddress();
//				String removeHostString=remoteAdd.getHostString();

//				PlatFormLog.sendLogRequest(Constants.config.getServerIp(), removeHostString, exeTime, dataSize,g.getCode());
//				PlatFormLog.sendLogProcessEnd(Integer.toString(g.getSeqNo()),g.getCode());
                byte[] respUtf8 = group.toByteArray();
                respUtf8 = Utils.byteMerger(respUtf8, Constants.config.getSeparator().getBytes());
                ByteBuf resp = PooledByteBufAllocator.DEFAULT
                        .buffer(respUtf8.length);
                resp.writeBytes(respUtf8);
                ctx.writeAndFlush(resp);
            }
        } catch (Exception e) {
            String warningMsg = "警告:" + e.getMessage();
            logger.warn(warningMsg, e);
            // 记录日志到服务平台
            MetadataInfo logMetadataInfo = new MetadataInfo();
            logMetadataInfo.setSysId(Constants.config.getSysId());
            logMetadataInfo.setHost(Constants.config.getServerIp());
            Constants.getLogService().sendLog(logMetadataInfo, LogLevel.WARNING, "NETTY", warningMsg);
            // 回复客户端
            Group group = BaseDataHandler.handleFilure(e.getMessage());
            byte[] respUtf8 = group.toByteArray();
            respUtf8 = Utils.byteMerger(respUtf8, Constants.config.getSeparator().getBytes());
            ByteBuf resp = PooledByteBufAllocator.DEFAULT
                    .buffer(respUtf8.length);
            resp.writeBytes(respUtf8);
            ctx.writeAndFlush(resp);
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
            throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent e = (IdleStateEvent) evt;
            if (e.state() == IdleState.READER_IDLE) {
                logger.info("a client READER_IDLE read time out");
            } else if (e.state() == IdleState.WRITER_IDLE) {
                logger.info("a client WRITER_IDLE write time out");
            } else if (e.state() == IdleState.ALL_IDLE) {
                logger.info("a client all_Idle_Time time out,close connect");
                ctx.close();
            }
        }
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        if (cause == null) {
            return;
        }
        if ("Connection reset by peer".equals(cause.getMessage())) {
            return;
        }
        String warningMsg = "警告:" + cause.getMessage();
        logger.warn(warningMsg, cause);
        ///PlatFormLog.sendLogErrorWarning(warningMsg,null);
        //Constants.getLogService().sendLog(SysName.SYSNAME_NETTY, LogLevel.WARNING,"通道消息处理","TimeServerHandler","channelRead","",warningMsg,Constants.config.getServerIp());
        MetadataInfo logMetadataInfo = new MetadataInfo();
        logMetadataInfo.setSysId(Constants.config.getSysId());
        logMetadataInfo.setHost(Constants.config.getServerIp());
        Constants.getLogService().sendLog(logMetadataInfo, LogLevel.WARNING, "NETTY", warningMsg);
    }
}
